﻿HmJS.$Import('log');
HmJS.$Import('core.object');
HmJS.$Import('core.element.event');
//HmJS.$Import('core.domready');

HmJS.register('demo.module.types.objectmoo', function ($) {
	var that = {};

	// Object对象静态方法(forEach, each)，对对象中的键值对进行迭代
	// 
	// Syntax: Object.each(obj, fn[, bind]);
	// 
	// Arguments: 
	//	obj - (object) 被迭代的对象 
	//	fn - (function) 迭代过程中对每个迭代元素进行处理的函数 
	//		语法：fn(item, index, object)
	//		Arguments: 
	//			item - (mixed) 当前迭代项 
	//			index - (number) 当前迭代项的对应键值(对象属性名) 
	//			object - (mixed) 迭代对象 
	//	bind - (object, 可选) 迭代函数中'this'所应用的对象. 详见 Function:bind. 
	// 
	// Returns: N/A
	that.each = function () {
		log.info("object.each()---->");
		Object.each({ first: 'Sunday', second: 'Monday' }, function (value, key) {
			log.info('The ' + key + ' day of the week is ' + value);
		});
	}

	// 合并一组对象生成新对象
	// 通过操作副本不破坏原来对象的情况下，吞并多个对象内容，如果第二个参数为string类型,则只吞并k: v 这种形式的属性对。
	// 即接受(obj1,obj2,obj3)产生的obj为obj1并带有后面两个对象的属性，重复属性被后者覆盖
	// 也接受(obj1,str,mix) ==>mix指的任意类型，这样返回的obj1多了一条形如  str:  mix 的属性
	that.merge = function () {
		log.info("object.merge()---->");
		var obj1 = { a: 0, b: 1 };
		var obj2 = { c: 2, d: 3 };
		var obj3 = { a: 4, d: 5 };
		var merged = Object.merge(obj1, obj2, obj3); // 返回新对象 {a: 4, b: 1, c: 2, d: 5}, (obj2 和 obj3 未被改变)
		log.info((merged === obj1) + '-obj1.length->' + Object.getLength(obj1)); // 表达式值为 true, obj1 被改变，作为合并后的对象被返回

		var nestedObj1 = { a: { b: 1, c: 1} };
		var nestedObj2 = { a: { b: 2} };
		var nested = Object.merge(nestedObj1, nestedObj2); // 返回: {a: {b: 2, c: 1}}
		var tmp = Object.merge(nestedObj1, 'moo', obj2, obj3); // 注意： 这时已把obj3这个参数忽略了
		Object.each(tmp.a, function (value, key) {
			log.info('tmp.a->' + key + '-' + value);
		});
		Object.each(tmp.moo, function (value, key) {
			log.info('tmp.moo->' + key + '-' + value);
		});
	}

	// 将第二个参数对象的所有属性复制到第一个参数对象中，重复属性被后者覆盖
	that.append = function () {
		log.info("object.append()---->");
		var firstObj = {
			name: 'John',
			lastName: 'Doe'
		};
		var secondObj = {
			age: '20',
			sex: 'male',
			lastName: 'Dorian'
		};
		Object.append(firstObj, secondObj); // firstObj 变成了: {name: 'John', lastName: 'Dorian', age: '20', sex: 'male'};
		Object.each(firstObj, function (value, key) {
			log.info('firstObj->' + key + '-' + value);
		});
	}

	// Get a subset of an object.(获得一个对象的子集)
	// Arguments: 
	//	object - (object) 源对象 
	//	keys - (array) 键值数组,也可以是一个key值的字符串
	that.subset = function () {
		log.info("object.subset()---->");
		var obj1 = {
			a: 'one',
			b: 'two',
			c: 'three'
		};
		//var obj2 = Object.subset(obj1, ['a', 'c']); // returns {a: 'one', c: 'three'}
		var obj2 = Object.subset(obj1, 'b');
		Object.each(obj2, function (value, key) {
			log.info('obj2->' + key + '-' + value);
		});
	}

	// Creates a new map with the results of calling a provided function on every value in the map
	// 对对象中的每个键值对进行迭代,并通过指定函数处理后重新映射成一个新的对象
	that.map = function () {
		log.info("object.map()---->");
		var myObject = { a: 1, b: 2, c: 3 };
		var timesTwo = Object.map(myObject, function (value, key) {
			return value * 2;
		}); // timesTwo now holds an object containing: {a: 2, b: 4, c: 6};
		Object.each(timesTwo, function (value, key) {
			log.info('timesTwo->' + key + '-' + value);
		});
	}

	// Creates a new object with all of the elements of the object for which the provided filtering function returns true.
	// 过滤对象中的键值对, 并将通过过滤的键值对组成一个新的对象
	that.filter = function () {
		log.info("object.filter()---->");
		var myObject = { a: 10, b: 20, c: 30 };
		var biggerThanTwenty = Object.filter(myObject, function (value, key) {
			return value > 20;
		}); // biggerThanTwenty now holds an object containing: {c: 30}
		Object.each(biggerThanTwenty, function (value, key) {
			log.info('biggerThanTwenty->' + key + '-' + value);
		});
	}

	// Returns true if every value in the object satisfies the provided testing function.
	// 迭代对象中的每个键值对, 如果每个迭代项都通过测试函数的测试, 则返回true
	that.every = function () {
		log.info("object.every()---->");
		var myObject = { a: 10, b: 4, c: 25, d: 100 };
		var areAllBigEnough = Object.every(myObject, function (value, key) {
			return value > 20;
		}); // areAllBigEnough = false
		log.info('areAllBigEnough->' + (areAllBigEnough));
	}

	// Returns true if at least one value in the object satisfies the provided testing function
	that.some = function () {
		log.info("object.some()---->");
		var myobject = { a: 10, b: 4, c: 25, d: 100 };
		var isanybigenough = Object.some(myobject, function (value, key) {
			return value > 20;
		}); //isanybigenough = true
		log.info('isanybigenough->' + (isanybigenough));
	}

	// Returns an array containing all the keys, in the same order as the values returned by Object:values.
	// 返回object的所有key组成的数组，即键数组
	that.keys = function () {
		log.info("object.keys()---->");
		var myObject = { a: 10, b: 4, c: 25, d: 100 };
		var aryKey = Object.keys(myObject);
		log.info('keys->' + aryKey.toString());
	}

	// Returns an array containing all the values, in the same order as the keys returned by Object:keys.
	// 返回object的所有value组成的数组，即值数组
	that.values = function () {
		log.info("object.values()---->");
		var myObject = { a: 10, b: 4, c: 25, d: 100 };
		var aryValue = Object.values(myObject);
		log.info('values->' + aryValue.toString());
	}

	// Returns the key of the specified value. Synonymous with Array:indexOf.
	// 返回某个值在object的键名
	that.keyOf = function () {
		log.info("object.keyOf()---->");
		var myObject = { a: 'one', b: 'two', c: 3 };
		log.info(Object.keyOf(myObject, 'two')); // returns 'b'
		log.info(Object.keyOf(myObject, 'four') == null); // returns null
	}

	// Tests for the presence of a specified value in the object.
	// 确定是否包含某个值
	that.contains = function () {
		log.info("object.contains()---->");
		var myObject = { a: 'one', b: 'two', c: 'three' };
		log.info(Object.contains(myObject, 'one')); // returns true
		log.info(Object.contains(myObject, 'four')); // returns false
	}

	// Generates a query string from key/value pairs in an object and URI encodes the values
	// Arguments: 
	//	object - (object) The object to generate the query string from.
	//	base - (string, optional) Will be used as base variable in the query string.
	/**
	* 将这个object的所有键值对转化为一个字符串
	* {key1:value1, key2 : value2 , key3: value3}转化为
	* 'key1=value1&key2=value2&key3=value3'
	* 每个value都要进行URI编码==>encodeURIComponent(value)
	**/
	that.toQueryString = function () {
		log.info("object.toQueryString()---->");
		log.info(Object.toQueryString({ apple: 'red', lemon: 'yellow' })); // returns 'apple=red&lemon=yellow'
		log.info(Object.toQueryString({ apple: 'red', lemon: 'yellow' }, 'fruits')); // returns 'fruits[apple]=red&fruits[lemon]=yellow'
	}

	// Returns a value of an object by its pat
	// 
	// Syntax: Object.getFromPath(myObject, path);
	// 
	// Arguments: 
	//	object - (object) The object to search in
	//	path - (string, array) the path to the key for the value you wish to retrieve
	// 
	// Returns: 
	//	(null or mixed) if the path has no value, null is returned; otherwise the value that corresponds to the path is returned.
	that.getFromPath = function () {
		log.info("object.getFromPath()---->");
		var obj1 = {
			food: {
				fruits: {
					apples: "red",
					lemon: "yellow"
				}
			}
		};
		var obj2 = {
			food: { pizza: 'yum!!' }
		};

		log.info(Object.getFromPath(obj1, 'food.fruits.apples')); // 'red'
		log.info(Object.getFromPath(obj1, ['food', 'fruits', 'lemon'])); // 'yellow'
		log.info(Object.getFromPath(obj2, ['food', 'pizza'])); // 'yum!!'
	}

	// Removes values from the object
	// 
	// Syntax: Object.cleanValues(myObject, method);
	// 
	// Arguments: 
	//	object - (object) The original object that should be cleaned up
	//	method - (function) The function that each value in the Hash is passed. If it returns true the value is kept. Defaults to check if the value != null.
	// 
	// Returns: 
	//	(object) - The cleaned object
	that.cleanValues = function () {
		log.info("object.cleanValues()---->");
		var obj1 = {
			foo: 'bar',
			something: 'else',
			missing: null
		};
		var obj2 = {
			a: -1,
			b: 2,
			c: 0,
			d: -5,
			e: 'moo good'
		};

		Object.cleanValues(obj1);

		//remove all values < 0
		Object.cleanValues(obj2, function (value) {
			if (typeOf(value) != "number") return true;
			return value > 0;
		});

		Object.each(obj1, function (value, key) {
			log.info('obj1->' + key + '-' + value);
		});
		Object.each(obj2, function (value, key) {
			log.info('obj2->' + key + '-' + value);
		});
	}

	// Deletes a property from the object.
	that.erase = function () {
		log.info("object.erase()---->");
		var alphabet = { a: 'a', b: 'b', c: 'c' };
		Object.erase(alphabet, 'b'); // alphabet == {a: 'a', c: 'c'};
		Object.each(alphabet, function (value, key) {
			log.info('alphabet->' + key + '-' + value);
		});
	}

	// Runs all the methods that are values of the object while passing any additional arguments passed to this function.
	// 
	// Syntax: Object.run(object[, arg1[, arg2[, ...]]])
	// 
	// Arguments: N/A
	// 
	// Returns: 
	//	(object) - The object.
	that.run = function () {
		log.info("object.run()---->");
		var initMyPage = {
			setupNav: function () {
				log.info('set up the nav');
			},
			setupSearch: function () {
				log.info('set up the search');
			}
		};
		Object.run(initMyPage);
	};

	return that;
});
